﻿#define _CRT_SECURE_NO_WARNINGS 1
#include<graphics.h>
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<windows.h> // 添加这一行为了用DeleteObject
//播放媒体需要的头文件和库
#include<mmsystem.h>
#pragma comment(lib,"winmm.lib")
//定义一个标识符流星图个数
#define NUM 100

IMAGE img_bk[2];//用于存放两张背景图片
IMAGE img_mt[2];//用于存放两张背景图片

//加载图片：开了空间，等用需要释放，用以下的Dobj函数
void loadimg()
{
	//加载背景图片
	loadimage(img_bk + 0/*首元素地址加偏移量就是地址*/, L"./背景/bj1.png", getwidth(), getheight());
	loadimage(img_bk + 1/*首元素地址加偏移量就是地址*/, L"./背景/bj2.png", getwidth(), getheight());
	//加载流星图片
	loadimage(img_mt + 0/*首元素地址加偏移量就是地址*/, L"./流星/lx1.png", 90, 90/*为了让流星合适点*/);
	loadimage(img_mt + 1/*首元素地址加偏移量就是地址*/, L"./流星/lx2.png", 90, 90/*为了让流星合适点*/);
}

//释放loadimage内存
void Dobj()
{
	//销毁背景图片
	DeleteObject(img_bk + 0); // 是windows.h库中的，销毁图片对象为了安全，防止内存未释放而造成说编译中断
	DeleteObject(img_bk + 1); // 是windows.h库中的，销毁图片对象为了安全，防止内存未释放而造成说编译中断
	//销毁流星图片
	DeleteObject(img_mt + 0); // 是windows.h库中的，销毁图片对象为了安全，防止内存未释放而造成说编译中断
	DeleteObject(img_mt + 1); // 是windows.h库中的，销毁图片对象为了安全，防止内存未释放而造成说编译中断
}

//封装开始界面
void Begin()
{
	//进来前播放音乐media多媒体 control控制 interface接口(有脸就是接口) send发送 string字符串
	mciSendString(L"open ./ThatGril.mp3 alias bgm", 0, 0, 0);//alias起别名:a一个 li李 as做为
	mciSendString(L"play bgm repeat", 0, 0, 0);//repeat重复播放

	//设置随机数种子，防止产生相同随机数
	srand((unsigned int)time(0));//要强制转换为unsigned int 否则1警告	warning C4244: “参数”: 从“time_t”转换到“unsigned int”，可能丢失数据


	//设置背景模式：让以下文字的背景为透明从而在背景图上只有单纯的字
	setbkmode(TRANSPARENT);//transparent:透明的意思tran跟随 s parent父母; 跟随父母一样那就是透明。

	//设置字体颜色：0代表自适应。
	settextstyle(27, 0, L"华文行楷");
	while (true)
	{
		//开始贴图
		putimage(0, 0, img_bk + 0);
		settextcolor(RGB(rand() % 256, rand() % 256, rand() % 256));//产生随机颜色
		outtextxy(500, 150, L"情至心间爱意绵绵不绝。");
		outtextxy(500, 200, L"两情相悦牵手共度良缘。");
		outtextxy(500, 250, L"三生有幸与你相伴永远。");
		outtextxy(500, 300, L"四季共度如影随形不变。");
		outtextxy(500, 350, L"五指紧握携手前行不悔。");
		outtextxy(500, 400, L"六神无主因你心动不已。");
		outtextxy(500, 450, L"七彩生活你我共绘精彩。");
		outtextxy(500, 500, L"八方风雨也不分离执着。");
		outtextxy(400, 550, L"愿我们的爱，如同这八行四字的承诺，坚定不移，直到永远。");
		//名字颜色与前面不同
		settextcolor(RGB(rand() % 256, rand() % 256, rand() % 256));//产生随机颜色
		settextstyle(40, 0, L"Matura MT Script Capitals");//设置字体颜色：0代表自适应。
		outtextxy(800, 600, L"------mingzhong");
		//爱心颜色与前面不同
		settextcolor(RGB(rand() % 256, rand() % 256, rand() % 256));//产生随机颜色
		settextstyle(25, 0, L"Matura MT Script Capitals"/*字体样式*/);//设置字体颜色：0代表自适应。
		for (int i = 0; i < 10; i++)
		{
			outtextxy(rand() % getwidth(), rand() % getheight(), L"💖💞💚");//一次只是出一次故我们用for循环
		}

		Sleep(500);


		//进行界面切换：   当界面1 动10秒后切换到界面二：用break跳出循环即可

		//动10秒:此时需要用到静态变量来记录时间//静态变量不会释放内存
		//使用clock_t类型变量 用clock()获得当前时间
		static clock_t start = 0;//初始时间为零
		if (clock() - start>10000)  //10000毫秒==10秒；
		{
			break;
		}

	}
}

//定义流星的结构体(我们自己定义一个我们觉得属于流星这一变量的类型)
//meteor: 流星
struct Meteor
{
	//贴流星图的位置坐标
	int x;
	int y;
	//改变流星图片的坐标从而达到视觉上的动的流星
	int speed;//速度
};

// 有结构体就得有初始化(对每个图进行初始化指出他们的初始位置和速度)
void Meteor_init(Meteor* p, int x, int y, int speed)//在c中学过结构体我们一般传址
{
	p->x = x;
	p->y = y;
	p->speed = speed;
}

//贴流星图
void Meteor_draw(Meteor* p)//通过p->##得出相应流星图起点
{
	putimage(p->x, p->y, img_mt + rand() % 2/*随机切换两个流星图达到闪烁效果*/, SRCPAINT);
	//srcpint:原图(背景图)按位或目标图=原图(背景图)和目标图背景合并为原图(背景图)：(前提是目标图背景为黑色)
}

//更行流星图:使流星动起来
void Meteor_updata(Meteor* p)
{
	p->x += p->speed;//p->x=p->x+p->speed;
	p->y += p->speed;//p->y=p->y+p->speed;

	//设置范围：刷新每次的时间
	if (p->y > 530)
	{
		//解决流星突兀问题使客观性能好让流星在第一、第二、第三象限左右出现
		p->x = rand() % (750 + 300) - 300;  //流星出现x坐标范围[-300, 750]
		p->y = rand() % (530 + 300) - 300;  //流星出现y坐标范围[-300,530]
	}
}


int main()
{
	initgraph(1200, 800);
	setbkcolor(WHITE);
	cleardevice();
	loadimg();//调用加载图片函数
	Begin();//调用开始界面


	//定义结构体Meteor数组变量存储多个流星图
	Meteor m[NUM];
	for (int i = 0; i < NUM; i++)
	{
		Meteor_init(m + i, rand() % (750 + 300) - 300, rand() % (530 + 300) - 300, rand() % 2 + 1);//对各个流星初始化
		//解决流星突兀问题使客观性能好让流星在第一、第二、第三象限左右出现
		//rand() % (750+300)-300       流星出现x坐标范围[-300,750]
		//rand() % (530 + 300) - 300   流星出现y坐标范围[-300,530]
	}

	while (true)//让他循环起来才会动
	{
		//防止闪屏：将这堆图打包绘画
		BeginBatchDraw();//batch打包 draw绘画

		//绘制（贴上）界面2 bj2.png
		putimage(0, 0, img_bk + 1);//注意：必须把这各写在循环内部最为流星轨迹的一个清屏操作；若不写则加上cleardecice();是达不到效果的
		//不用写在for里面for中是将一堆流星图在该背景上绘制；

		for (int i = 0; i < NUM; i++)
		{
			Meteor_draw(m + i);//绘制各个流星
			Meteor_updata(m + i);//流星动起来
		}
		//结束打包
		EndBatchDraw();

		Sleep(10);//让程序慢下来
	}
	getchar(); // 使用getchar()代替system("pause")来暂停程序
	Dobj();//等一切完了后在return 0;和closegraph();前调用释放函数
	closegraph(); // 关闭图形模式
	return 0;
}